package com.starview.star.compiler.cafe.compile.cont;

import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.MethodNode;

import com.starview.platform.data.type.Location;
import com.starview.star.code.repository.CodeCatalog;
import com.starview.star.compiler.ErrorReport;
import com.starview.star.compiler.cafe.compile.CafeDictionary;
import com.starview.star.compiler.cafe.compile.CodeContext;
import com.starview.star.compiler.cafe.compile.Expressions;
import com.starview.star.compiler.cafe.compile.HWM;
import com.starview.star.compiler.cafe.compile.ISpec;
import com.starview.star.compiler.cafe.compile.SrcSpec;

public class CheckCont implements IContinuation
{
  private final LabelNode jmp;
  private final ISpec expect;
  private final CafeDictionary dict;

  public CheckCont(LabelNode jmp, ISpec expect, CafeDictionary dict)
  {
    this.jmp = jmp;
    this.expect = expect;
    this.dict = dict;
  }

  @Override
  public ISpec cont(ISpec src, CafeDictionary cxt, Location loc, ErrorReport errors, CodeContext ccxt)
  {
    MethodNode mtd = ccxt.getMtd();
    HWM hwm = ccxt.getMtdHwm();
    CodeCatalog bldCat = ccxt.getBldCat();
    
    Expressions.checkType(src, expect, mtd, dict, hwm, loc, errors, bldCat);
    InsnList ins = mtd.instructions;
    if (!JumpCont.isUnconditionalJump(ins.getLast().getOpcode()))
      ins.add(new JumpInsnNode(Opcodes.GOTO, jmp));
    return SrcSpec.prcSrc;
  }

  @Override
  public boolean isJump()
  {
    return true;
  }

}
